package acadclockmidletpkg;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Date;
import javax.microedition.lcdui.DateField;
import javax.microedition.lcdui.TextField;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;

/**
 * Класс, инкапсулирующий функциональность создания и работы с RMS-хранилищем
 * значений настроек программы.
 *
 * @author Kolomoets G.P.
 * @version 1.0
 */
public class RMSWorker {

    private RecordStore rs = null;
    public final String nameDB = "AcademicClockSettings";

    /**
     * Инициализация хранилища записей. Для пустой базы создаётся 12 записей 
     * с текущими датой, временем и значением длительности пар 
     * по-умолчанию - 75 мин.
     * Если количество записей превышает 12, база очищается.
     * Если количество записей равно 12 - ничего не делается.
     */
    public void initializeRecordStore() {
        try {
            DateField df = new DateField("", DateField.DATE);
            df.setDate(new Date(System.currentTimeMillis()));
            TextField tf = new TextField("", "75", 3, 0);
            rs = RecordStore.openRecordStore(nameDB, true);
            int numRecords = rs.getNumRecords();
            //Отладочный вывод
//            System.out.println("Last Records ID is: " + (rs.getNextRecordID() - 1));
            /*Для пустой базы*/
            if (numRecords == 0) {
                saveDateRecord(df); //recordId=1 - firstSemesterBegin
                saveDateRecord(df); //recordId=2 - secondSemesterBegin
                saveTextRecord(tf); //recordId=3 - pairDuration
                for (int i = 4; i <= 12; i++) {
                    saveDateRecord(df); ////recordId=4-12 - pairsBegin
                }
             /*Для базы с количеством записей больше 12*/
            } else if (rs.getNextRecordID() != 13) {
                closeRecordStore();
                RecordStore.deleteRecordStore(nameDB);
            }
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Закрытие хранилища.
     */
    public void closeRecordStore() {
        try {
            if (rs != null) {
                rs.closeRecordStore();
            }
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Сохранение значений даты и/или времени в базе.
     * @param df - поле даты/времени на форме настроеек
     * @return идентификатор записи
     */
    public int saveDateRecord(DateField df) {
        int recordId = 0;
        ByteArrayOutputStream baout = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(baout);
        try {
            RecordStore.openRecordStore(nameDB, false);
            long date = df.getDate().getTime();
            dout.writeLong(date);
            byte[] data = baout.toByteArray();
            recordId = rs.addRecord(data, 0, data.length);
            dout.close();
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        closeRecordStore();
        return recordId;
    }

    /**
     * Сохранение значений текстового поля в базе.
     * @param df - текстовое поле на форме настроеек
     * @return идентификатор записи
     */
    public int saveTextRecord(TextField tf) {
        int recordId = 0;
        ByteArrayOutputStream baout = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(baout);
        try {
            RecordStore.openRecordStore(nameDB, false);
            dout.writeUTF(tf.getString());
            byte[] data = baout.toByteArray();
            recordId = rs.addRecord(data, 0, data.length);
            dout.close();
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        closeRecordStore();
        return recordId;
    }

    /**
     * Обновление значений даты и/или времени в базе.
     * @param df - поле даты/времени на форме настроеек
     */
    public void updateDateRecord(int recordId, DateField df) {
        ByteArrayOutputStream baout = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(baout);
        try {
            RecordStore.openRecordStore(nameDB, false);
            long date = df.getDate().getTime();
            dout.writeLong(date);
            byte[] data = baout.toByteArray();
            rs.setRecord(recordId, data, 0, data.length);
            dout.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
        closeRecordStore();
    }

    /**
     * Обновление значений текстового поля в базе.
     * @param df - текстовое поле на форме настроеек
     */
    public void updateTextRecord(int recordId, TextField tf) {
        ByteArrayOutputStream baout = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(baout);
        try {
            RecordStore.openRecordStore(nameDB, false);
            dout.writeUTF(tf.getString());
            byte[] data = baout.toByteArray();
            rs.setRecord(recordId, data, 0, data.length);
            dout.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
        closeRecordStore();
    }

    /**
     * Чтение значений даты и/или времени для поля формы настроеек из базы.
     * @param recordId идентификатор записи
     * @return объект Date со значением даты/времени
     */
    public Date readDateRecord(int recordId) {
        Date date = new Date();
        byte[] data;
        ByteArrayInputStream bain;
        DataInputStream din;
        try {
            RecordStore.openRecordStore(nameDB, false);
            data = rs.getRecord(recordId);
            bain = new ByteArrayInputStream(data);
            din = new DataInputStream(bain);
            long value = din.readLong();
            date.setTime(value);
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        closeRecordStore();
        return date;
    }
    
    /**
     * Чтение значений для текстового поля формы настроеек из базы.
     * @param recordId идентификатор записи
     * @return Строковое значение, извлечённое из БД
     */
    public String readTextRecord(int recordId) {
        String value = null;
        byte[] data;
        ByteArrayInputStream bain;
        DataInputStream din;
        try {
            RecordStore.openRecordStore(nameDB, false);
            data = rs.getRecord(recordId);
            bain = new ByteArrayInputStream(data);
            din = new DataInputStream(bain);
            value = din.readUTF();
            /*Пришлось предотвратить появление пустой строки,
             т.к. использующий этот метод код парсит это значение
             в long*/
            if ("".equals(value))
                value="75";
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        closeRecordStore();
        return value;
    }   
}
